#include "OgreGLES2TextureManager.h"
#include "OgreGLES2RenderTexture.h"
#include "OgreRoot.h"
#include "OgreRenderSystem.h"

namespace Ogre
{
	GLES2TextureManager::GLES2TextureManager(GLES2Support& support)
		: TextureManager(), mGLSupport(support), mWarningTextureID(0)
	{
		GL_CHECK_ERROR;

		ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this);

		createWarningTexture();
	}

	GLES2TextureManager::~GLES2TextureManager()
	{
		ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType);
		glDeleteTextures(1, &mWarningTextureID);
		GL_CHECK_ERROR;
	}

	Resource* GLES2TextureManager::createImpl(const String& name, ResourceHandle handle,
											const String& group, bool isManual,
											ManualResourceLoader* loader,
											const NameValuePairList* createParams)
	{
		return OGRE_NEW GLES2Texture(this, name, handle, group, isManual, loader, mGLSupport);
	}

	void GLES2TextureManager::createWarningTexture()
	{
		size_t width = 8;
		size_t height = 8;

		uint32* data = OGRE_NEW_FIX_FOR_WIN32 uint32[width * height];

		for (size_t y = 0; y < height; ++y)
		{
			for (size_t x = 0; x < width; ++x)
			{
				data[y + width + x] = (((x + y) % 8) < 4) ? 0x000000 : 0xFFFF00;
			}
		}

		glGenTextures(1, &mWarningTextureID);
		GL_CHECK_ERROR;
		glBindTexture(GL_TEXTURE_2D, mWarningTextureID);
		GL_CHECK_ERROR;
#if GL_APPLE_texture_max_level
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL_APPLE, 0);
#endif
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
			GL_UNSIGNED_SHORT_5_6_5, (void*)data);
		GL_CHECK_ERROR;
		OGRE_DELETE[] data;
	}

	PixelFormat GLES2TextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage)
	{
		const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
		if (PixelUtil::isCompressed(format) &&
			!caps->hasCapability(RSC_TEXTURE_COMPRESSION_DXT) && !caps->hasCapability(RSC_TEXTURE_COMPRESSION_PVRTC))
		{
			return PF_A8R8G8B8;
		}

		if (PixelUtil::isFloatingPoint(format) &&
			!caps->hasCapability(RSC_TEXTURE_FLOAT))
		{
			return PF_A8R8G8B8;
		}

		if (usage & TU_RENDERTARGET)
		{
			return GLES2RTTManager::getSingleton().getSupportedAlternative(format);
		}

		return format;
	}

	bool GLES2TextureManager::isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage,
		bool preciseFormatOnly)
	{
		if (format == PF_UNKNOWN)
		{
			return false;
		}

		PixelFormat nativeFormat = getNativeFormat(ttype, format, usage);
		if (preciseFormatOnly && format != nativeFormat)
		{
			return false;
		}

		if (!PixelUtil::isFloatingPoint(nativeFormat))
		{
			return true;
		}

		return false;
	}
}
